package com.tusuo.stds.util;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.telephony.TelephonyManager;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.SpannedString;
import android.text.TextUtils;
import android.util.Base64;
import android.util.TypedValue;
import android.widget.TextView;

import com.jude.utils.JUtils;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tusuo.stds.Constants;
import com.tusuo.stds.rest.Question;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * @author J.Huang
 * @version 1.0
 *
 */

public class Utils {

    public static class UI {
        public static void showToastShort(String text) {
            JUtils.Toast(text);
        }

        public static void showToastLong(String text) {
            JUtils.ToastLong(text);
        }

        public static void closeInputMethod(Activity activity) {
//            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
            JUtils.closeInputMethod(activity);
        }

        private static long lastClickTime;

        public static boolean isFastDoubleClick() {
            long time = System.currentTimeMillis();
            long timeDiff = time - lastClickTime;
            if (timeDiff > 0 && timeDiff < 500) {
                return true;
            }
            lastClickTime = time;
            return false;
        }

        public static boolean isFastSwipe() {
            long time = System.currentTimeMillis();
            long timeDiff = time - lastClickTime;
            if (timeDiff > 0 && timeDiff < 800) {
                return true;
            }
            lastClickTime = time;
            return false;
        }
    }

    public static class Network {
        public static boolean isNetworkAvailable() {
            return JUtils.isNetWorkAvilable();
        }
    }

    public static class App {
        public static int getAppVersionCode() {
            return JUtils.getAppVersionCode();
        }

        public static String getAppVersionName() {
            return JUtils.getAppVersionName();
        }

        public static boolean isWXAppInstalled(Context context) {
            List<ApplicationInfo> list = context.getPackageManager().getInstalledApplications(0);

            for (ApplicationInfo info :
                    list) {
                if ("com.tencent.mm".equals(info.packageName)) {
                    return true;
                }
            }

            return false;
        }

        public static boolean isQQAppInstalled(Context context) {
            List<ApplicationInfo> list = context.getPackageManager().getInstalledApplications(0);

            for (ApplicationInfo info :
                    list) {
                if ("com.tencent.mobileqq".equals(info.packageName)) {
                    return true;
                }
            }

            return false;
        }

        public static boolean isWxAppSupported(Context context) {
            IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
            msgApi.registerApp(Constants.WECHAT_APP_ID);

            return msgApi.isWXAppInstalled()
                    && msgApi.isWXAppSupportAPI();
        }
    }



    public static class Device {
        public static String getDeviceUniqueId(Context context) {
            final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

            final String tmDevice, tmSerial, androidId;
            tmDevice = "" + tm.getDeviceId();
            tmSerial = "" + tm.getSimSerialNumber();
            androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);

            UUID deviceUuid = new UUID(androidId.hashCode(),
                    ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
            return deviceUuid.toString();
        }
    }


    public double getArea() {
        double area = 0;
        int r = 4;
        int l = 5;
        area = 2 * r * Math.PI + (l - r) * 2;
        return area;
    }

    public double getLength() {
        double length = 0;
        int r = 4;
        int l = 5;
        length = Math.PI * r * l;
        return length;
    }

    public static class Image {
        /***
         * 将Bitmap转换成Base64字符串
         * @param bitmap
         * @return
         */
        public static String bitmap2StrByBase64(Bitmap bitmap, String format) {
            if (bitmap == null) {
                return "";
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Bitmap.CompressFormat compressFormat;
            switch (format.toLowerCase()) {
                case "jpg":
                case "jpeg":
                    compressFormat = Bitmap.CompressFormat.JPEG;
                    break;
                case "png":
                    compressFormat = Bitmap.CompressFormat.PNG;
                    break;
                default:
                    return null;
            }
            //参数100表示不压缩
            bitmap.compress(compressFormat, 80, baos);

            byte[] bytes = baos.toByteArray();

            try {
                baos.flush();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return Base64.encodeToString(bytes, Base64.DEFAULT);
        }

        public static Bitmap getBitmap(String srcPath) {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            //开始读入图片，此时把options.inJustDecodeBounds 设回true了
            newOpts.inJustDecodeBounds = true;
            // 获取图片参数
            BitmapFactory.decodeFile(srcPath, newOpts);

            Bitmap bitmap;
            newOpts.inJustDecodeBounds = false;
            int w = newOpts.outWidth;
            int h = newOpts.outHeight;
            float width = 800f;//这里设置宽度为480f
            float height = width * h / w;
            // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
            int be = 1;//be=1表示不缩放
            if (w > width) {
                be = (int) (w / width);
                newOpts.inSampleSize = be;//设置缩放比例
                //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
                bitmap = zoomImage(BitmapFactory.decodeFile(srcPath, newOpts), width, height);
            } else {
                newOpts.inSampleSize = 1;
                bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
            }
            return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
        }

        /***
         * 图片的缩放方法
         *
         * @param bitmap   ：源图片资源
         * @param newWidth  ：缩放后宽度
         * @param newHeight ：缩放后高度
         * @return
         */
        public static Bitmap zoomImage(Bitmap bitmap, float newWidth,
                                       float newHeight) {
            // 获取这个图片的宽和高
            float width = bitmap.getWidth();
            float height = bitmap.getHeight();
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            // 计算宽高缩放率
            float scaleWidth = newWidth / width;
            float scaleHeight = newHeight / height;
            // 缩放图片动作
            matrix.postScale(scaleWidth, scaleHeight);
            return Bitmap.createBitmap(bitmap, 0, 0, (int) width,
                    (int) height, matrix, true);
        }

        public static Bitmap compressImage(Bitmap image) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
            int options = 100;
            while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();//重置baos即清空baos
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%，把压缩后的数据存放到baos中
                options -= 10;//每次都减少10
            }
            ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
            return BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        }

        public static byte[] bitmap2Bytes(Bitmap bitmap, boolean paramBoolean) {
            Bitmap localBitmap = Bitmap.createBitmap(120, 120, Bitmap.Config.ARGB_8888);
            Canvas localCanvas = new Canvas(localBitmap);
            int i;
            int j;
            if (bitmap.getHeight() > bitmap.getWidth()) {
                i = bitmap.getWidth();
                j = bitmap.getWidth();
            } else {
                i = bitmap.getHeight();
                j = bitmap.getHeight();
            }
            while (true) {
                localCanvas.drawBitmap(bitmap, new Rect(0, 0, i, j), new Rect(0, 0, 120, 120), null);
                if (paramBoolean)
                    bitmap.recycle();
                ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
                localBitmap.compress(Bitmap.CompressFormat.JPEG, 100,
                        localByteArrayOutputStream);
                localBitmap.recycle();
                byte[] arrayOfByte = localByteArrayOutputStream.toByteArray();
                try {
                    localByteArrayOutputStream.close();
                    return arrayOfByte;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                i = bitmap.getHeight();
                j = bitmap.getHeight();
            }
        }

//        public static byte[] getImageBytesFromUrl(String strUrl) throws IOException {
//            URL url = new URL(strUrl);
//            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//            conn.setRequestMethod("GET");   //设置请求方法为GET
//            conn.setReadTimeout(5*1000);    //设置请求过时时间为5秒
//            InputStream inputStream = conn.getInputStream();   //通过输入流获得图片数据
//            return getBytesFromInputStream(inputStream);     //获得图片的二进制数据
//        }

        public static Bitmap drawableToBitmap(Drawable drawable) {
            int width = drawable.getIntrinsicWidth();
            int height = drawable.getIntrinsicHeight();
            Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                    : Bitmap.Config.RGB_565;
            Bitmap bitmap = Bitmap.createBitmap(width, height, config);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, width, height);
            drawable.draw(canvas);
            return bitmap;
        }

        public static Drawable zoomDrawable(Resources resources, Drawable drawable, int maxWidth, int maxHeight) {
            int width = drawable.getIntrinsicWidth();
            int height = drawable.getIntrinsicHeight();
            Bitmap oldMp = drawableToBitmap(drawable);
            Matrix matrix = new Matrix();
//            float scaleWidth = (float) w / width;
            float scaleHeight = (float) maxHeight / height;
            float scaleWidth;
            if (scaleHeight * width > maxWidth) {
                scaleWidth = (float) maxWidth / width;
            } else {
                scaleWidth = scaleHeight;
            }

            matrix.postScale(scaleWidth, scaleHeight);
            Bitmap newBmp = Bitmap.createBitmap(oldMp, 0, 0, width, height, matrix, true);
            return new BitmapDrawable(resources, newBmp);
        }
    }

    public static class Text {
        /*由于Java是基于Unicode编码的，因此，一个汉字的长度为1，而不是2。
     * 但有时需要以字节单位获得字符串的长度。例如，“123abc长城”按字节长度计算是10，而按Unicode计算长度是8。
     * 为了获得10，需要从头扫描根据字符的Ascii来获得具体的长度。如果是标准的字符，Ascii的范围是0至255，如果是汉字或其他全角字符，Ascii会大于255。
     * 因此，可以编写如下的方法来获得以字节为单位的字符串长度。*/
        public static int getWordCount(String s) {
            int length = 0;
            for(int i = 0; i < s.length(); i++)
            {
                int ascii = Character.codePointAt(s, i);
                if(ascii >= 0 && ascii <=255)
                    length++;
                else
                    length += 2;

            }
            return length;
        }

        /*基本原理是将字符串中所有的非标准字符（双字节字符）替换成两个标准字符（**，或其他的也可以）。这样就可以直接例用length方法获得字符串的字节长度了*/
        public static int getWordCountRegex(String s) {
            s = s.replaceAll("[^\\x00-\\xff]", "**");
            return s.length();
        }

        public static String getTruncatedString(String validateStr, int maxLen) {
            if (getWordCountRegex(validateStr) > maxLen) {
                String chinese = "[\u4e00-\u9fa5]";
                int len = 0;
                String str = "";

                for (int i = 0; i < validateStr.length(); i++) {
                    /* 获取一个字符 */
                    String temp = validateStr.substring(i, i + 1);
                    /* 判断是否为中文字符 */
                    if (temp.matches(chinese)) {
                        /* 中文字符长度为2 */
                        len += 2;
                    } else {
                    /* 其他字符长度为1 */
                        len += 1;
                    }

                    if (len <= maxLen) {
                        str = str + temp;
                    } else {
                        break;
                    }
                }

                return str;
            } else {
                return validateStr;
            }
        }
    }

    public static String secondsToHumanReadable(int secondCount) {
        int minutes = secondCount / 60;
        int seconds = secondCount % 60;
        return String.format("%d'%02d\"", minutes, seconds);
    }

    public static Spanned fromHtml(Context context, TextView textView, String html) {
        return fromHtml(context, textView, html, false);
    }

        @SuppressWarnings("deprecation")
    public static Spanned fromHtml(Context context, TextView textView, String html, boolean limited){
        Spanned result;

//        Html.ImageGetter imgGetter = new Html.ImageGetter() {
//            public Drawable getDrawable(String source) {
//                Drawable drawable = null;
//                URL url;
//                try {
//                    url = new URL(source);
////                    drawable = Drawable.createFromStream(url.openStream(), "");  //获取网路图片
//                    drawable = Drawable.createFromResourceStream(context.getResources(), null, url.openStream(), null);  //获取网路图片
//                } catch (Exception e) {
//                    return null;
//                }
//                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
//                        .getIntrinsicHeight());
//                return drawable;
//            }
//        };

        URLImageParser parser = new URLImageParser(context, textView, limited);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            result = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY, parser, null);
        } else {
            result = Html.fromHtml(html, parser, null);
        }
        return result;
    }

    public static String getFileExtensionFromUrl(String url) {
        if (!TextUtils.isEmpty(url)) {
            int fragment = url.lastIndexOf("#");
            if (fragment > 0) {
                url = url.substring(0, fragment);
            }

            int query = url.lastIndexOf("?");
            if (query > 0) {
                url = url.substring(0, query);
            }

            int filenamePos = url.lastIndexOf(File.separator);
            String filename =
                    0 <= filenamePos ? url.substring(filenamePos + 1) : url;

            // if the filename contains special characters, we don't
            // consider it valid for our matching purposes:
            if (!filename.isEmpty()) {
                int dotPos = filename.lastIndexOf(".");
                if (0 <= dotPos) {
                    return filename.substring(dotPos + 1);
                }
            }
        }

        return "";
    }

    public static void routineCheckVersion(final Activity activity, int remoteVersionCode, String downloadUrl, boolean forceUpdate, SharedPreferences sharedPref) {
        long lastCheck = sharedPref.getLong("checkUpdateTime", 0);
        long now = System.currentTimeMillis();
        if (now - lastCheck > 12 * 60 * 60 * 1000) {    // 每12个小时检查一遍是否更新
            SharedPreferences.Editor editor = sharedPref.edit();
            editor.putLong("checkUpdateTime", now);
            editor.apply();

            if (remoteVersionCode > Utils.App.getAppVersionCode()) {
                DialogUtils.showUpdateDialog(activity, downloadUrl, sharedPref, forceUpdate);
            }
        }
    }

    public static boolean manualCheckVersion(final Activity activity, int remoteVersionCode, String downloadUrl, boolean forceUpdate, SharedPreferences sharedPref) {
        long now = System.currentTimeMillis();
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putLong("checkUpdateTime", now);
        editor.apply();

        if (remoteVersionCode > Utils.App.getAppVersionCode()) {
            DialogUtils.showUpdateDialog(activity, downloadUrl, sharedPref, forceUpdate);
            return true;
        } else {
            return false;
        }
    }

    public static Set<Integer> getUserChoice(Question question) {
        Set<Integer> choiceSet = new HashSet<>();

        if (TextUtils.isEmpty(question.AnswerContent)) {
            return choiceSet;
        }

        if ("对".equals(question.AnswerContent)) {
            choiceSet.add(0);
        } else if ("错".equals(question.AnswerContent)) {
            choiceSet.add(1);
        } else {
            for (int i = 0; i < question.QuestionOptionList.size(); i++) {
                Question.QuestionOption option = question.QuestionOptionList.get(i);
                if (question.AnswerContent.contains(option.Id)) {
                    choiceSet.add(i);
                }
            }
        }

        return choiceSet;
    }

    public static String getCorrectImageUrl(String url) {
        String imageUrl = "";

        if (!TextUtils.isEmpty(url)) {
            if (url.startsWith("http")) {
                imageUrl = url;
            } else {
                imageUrl = Constants.ENDPOINT + url;
            }
        }

        return imageUrl;
    }

    /**
     * 将dp转换为px
     * @param dp
     * @param context
     * @return
     */
    public static int dp2px(int dp,Context context) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                context.getResources().getDisplayMetrics());
    }

}
